/*
 * Copyright 2008 Nathan C Jones
 * 
 * This file is part of Fivehundred.
 * 
 * Fivehundred is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * Fivehundred is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * Fivehundred. If not, see <http://www.gnu.org/licenses/>. 
 */

package com.googlecode.fivehundred.ui.simple;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;

/**
 * <p>
 * A layout that overlaps components with a fixed offset from each other.
 * </p>
 * TODO this layout manager should be able to be either horizontal or vertical
 * and reverse
 * 
 * @author Nathan C Jones
 */
public class CascadeLayout implements LayoutManager {

	/** The gap between overlapped components. */
	private int cascadeGap;

	/**
	 * Create a cascading layout with no gap between components. Components will
	 * be stacked on top of each other.
	 */
	public CascadeLayout() {
		this(0);
	}

	/**
	 * Create a new cascading layout.
	 * 
	 * @param cascadeGap the gap between each overlapped component.
	 */
	public CascadeLayout(final int cascadeGap) {
		this.cascadeGap = cascadeGap;
	}

	/**
	 * @return the size of the gap between each cascaded component.
	 */
	public int getCascadeGap() {
		return cascadeGap;
	}

	/**
	 * Set the size of the gap between cascaded components.
	 * 
	 * @param the new gap between cascaded components.
	 */
	public void setCascadeGap(int cascadeGap) {
		this.cascadeGap = cascadeGap;
	}

	/**
	 * Adds the specified component to the layout. Not used by this class.
	 * 
	 * @param name the name of the component
	 * @param comp the component to be added
	 */
	public void addLayoutComponent(String name, Component comp) {
	}

	/**
	 * Removes the specified component from the layout. Not used by this class.
	 * 
	 * @param comp the component to remove
	 * @see java.awt.Container#removeAll
	 */
	public void removeLayoutComponent(Component comp) {
	}
	
	//TODO account for insets due to border

	@Override
	public void layoutContainer(Container parent) {
		synchronized (parent.getTreeLock()) {
			final int componentCount = parent.getComponentCount();
			for (int i = 0; i < componentCount; i++) {
				final Component c = parent.getComponent(i);
				final Dimension d = c.getPreferredSize();
				c.setSize(d);
				c.setLocation(getCascadeGap() * (componentCount - i - 1), 0);
			}
		}
	}

	/**
	 * Same as the preferred size.
	 */
	@Override
	public Dimension minimumLayoutSize(Container parent) {
		return preferredLayoutSize(parent);
	}

	/**
	 * Gets the size of the laid-out container.
	 */
	@Override
	public Dimension preferredLayoutSize(Container parent) {
		final Dimension layoutSize = new Dimension(0, 0);
		Component lastComponent = null;
		int widestComponentWidth = 0;
		final int componentCount = parent.getComponentCount();
		for (int i = 0; i < componentCount; i++) {
			final Component c = parent.getComponent(i);
			layoutSize.height = Math.max(layoutSize.height, c.getPreferredSize().height);
			widestComponentWidth = c.getPreferredSize().width;
			lastComponent = c;
		}
		layoutSize.width += getCascadeGap() * (componentCount - 1);
		if (lastComponent != null) {
			layoutSize.width += lastComponent.getPreferredSize().width;
		}
		layoutSize.width = Math.max(layoutSize.width, widestComponentWidth);
		return layoutSize;
	}

}
